//This script moves linksets from original link module to another specified link module. //Written by Lantian Li // Updated by John Earnshaw 7/8/2015) // Update by John Rowland 11-Jan-2017: // added setLinkModuleDescriptorsExclusive calls before and after transferring the links. // Added pre- and post- transfer link dump for performance validation (credit Matthias Mamsch for original code) /*////////////////////////// General Comments on script behaviour///////////////////////// The script will run on the user defined link module (a few lines below) and will move all linksets in that link module to a different specified link module. To do this, it first updates a module's link module descriptor, then creates all links through the old LM, using the new LM. If successful it will delete the link going through the old link module. SEE LINES 106-108 REQUIRED USER INPUT ////////////////////////////////////////////////////////////////////////////////////////*/ pragma runLim, 0 Module oldlm, newlm, m1, m2 Object o, o1, o2 Linkset oldLinkset string sourceM = "" string targetM = "" string oldlmName = "" string newlmName = "" string str, str3, str4 string error = "" string lineSeparator = "\n" string fieldSeparator = "\t" Link l Skip oldLinkList = create Skip oldLinkSets = create Skip skpLinks = create Folder f DB db DBE lbl, list1 bool cont = false bool dontDelete string sFileName; Stream stPre; sFileName = tempFileName() ".txt"; print "Pre-transfer link dump: " sFileName "\n"; stPre = write sFileName Stream stPost; sFileName = tempFileName() ".txt"; print "Pre-transfer link dump: " sFileName "\n"; stPost = write sFileName Buffer bufLink = create() void Continue(DB box) { cont = true release box } void addModuleVersion (Buffer bufLink, ModuleVersion mv) { bufLink += name mv bufLink += fieldSeparator if (versionString mv != "") { bufLink += versionString mv bufLink += fieldSeparator } } void reportLink (Stream st, Link L) { // A dump Link function that will write a link to a file (modified from work by Matthias Mamsch) ModuleVersion mvSource = sourceVersion L ModuleVersion mvLink = linkVersion L ModuleVersion mvTarget = targetVersion L bufLink = "" // Source Module + Version + Object Abs No addModuleVersion (bufLink, mvSource) bufLink += sourceAbsNo L "" bufLink += fieldSeparator // Link Module + Version addModuleVersion (bufLink, mvLink) // Target Module, Version + Object AbsNo addModuleVersion (bufLink, mvTarget) bufLink += targetAbsNo L "" bufLink += fieldSeparator // Info about echoed vs. non echoed link bufLink += echo L "" bufLink += lineSeparator st << bufLink delete mvSource delete mvLink delete mvTarget } void reportModule (Stream st, Module mod) { Object o Link L //print "link dump for source module " name(m1) ": " sFile "\n" for o in entire mod do { for L in all (o->"*") do { reportLink (st, L) } } flush st } ////////////////////////////////USER INPUTS BELOW///////////////////////////////////////// // Move Links From: string lmn = "/Sandbox/practice/John Rowland/Verification Management/Design Requirements/supports" // To: newlmName = "/Sandbox/practice/John Rowland/Verification Management/Link Modules/satisfies" ////////////////////////////////////////////////////////////////////////////////////////// if (lmn == newlmName) { ack ("Link modules must have different names") halt } oldlm = edit(lmn, false, true, true) newlm = edit(newlmName, false, true, true) string message = "" for o in oldlm do { message = message o."source" "" " -> " o."target" "" "\n" } //Prompt the user to confirm if this is the linkset to be moved. cont = false db = centered "Move Linkset" list1 = text(db, "The following linksets will be moved to " newlmName " (nonexistent linkset will be skipped):", message, 600, 200, true) apply(db, "Continue", Continue) block db if(!cont) halt LinkModuleDescriptor lmd //Iterate through each linkset and 'move' them to the new link module for o in oldlm do { sourceM = o."source" "" targetM = o."target" "" m1 = edit(sourceM, false, true, true) if(null m1) { error = error sourceM " can not be opened.\n" } else if (!isEdit(m1)) { ack fullName(m1)"" " can not be opened for edit" close m1 } else { f = getParentFolder(m1) setLinkModuleDescriptorsExclusive(f, module(m1), false); reportModule (stPre, m1) m2 = read(targetM, false, true) if(null m2) { error = error targetM " can not be opened.\n" } else if (!isEdit(m1)) { ack fullName(m1)"" " can not be opened for edit(2)" close m1 if (!null(m2)) close m2 } else { //Remove the original linkset pairing, and create a new linkset pairing and linset for the new link module. str3 = removeLinkModuleDescriptor(f, sourceM, targetM) if(str3 == "") { flushDeletions str4 = addLinkModuleDescriptor(f, sourceM, targetM, false, true, newlmName, "") } else { error = error str3 "\n" close(m1,false) if (!null m2) close(m2,false) continue } if (str4 != "") { error = error str4 "\n" close(m1,false) if (!null m2) close(m2,false) continue } //Iterate through objects in the source module to identify the links that belongs to the linkset we want to move. dontDelete = false for o1 in all(m1) do { if (!canModify(o1)) { error = error "can not modify " fullName(m1)"->" o."Absolute Number""\n" continue } else { for l in o1 -> lmn do { put (skpLinks, l, l) } } for l in skpLinks do { if(targetM == fullName(target(l))) { o2 = target(l) //Create a new link to replace the old one with new link module. if(!null o2 && !isDeleted o2) { noError o1 -> newlmName -> o2 string lasterror = lastError if(null lasterror) { put(oldLinkList, l, l); } else { error = error lasterror "\n" dontDelete = true } } else if (!null o2 && isDeleted o2) { error = error "Object " o2."Absolute Number""" " in " targetM " is Deleted.\n" } else { error = error o1."Absolute Number""" "in" sourceM "has null outlink\n" } } } delete skpLinks skpLinks = create } if (!dontDelete) { for l in oldLinkList do { delete l } flushDeletions } delete oldLinkList oldLinkList = create //Open the old link module and delete the old linkset. if(!dontDelete) { oldLinkset = linkset o put (oldLinkSets,oldLinkset,oldLinkset) } else error = error "Not all links from " sourceM " could be created\n" if (m1==m2) { save m2 close m2 continue } close m2 } if (!null m1) { setLinkModuleDescriptorsExclusive(f, module(m1), true); save m1 reportModule (stPost, m1) close m1 } } } for oldLinkset in oldLinkSets do { str4 = delete oldLinkset if (str4!= "") error = error str4 "\n" } save oldlm close oldlm save newlm close newlm //Error Feedback. if(error!="") { db = centered "Move Linkset" list1 = text(db, "The following errors occurred:", error, 650, 200, true) apply(db, "OK", Continue) block db } else { db = centered "Move Linkset" lbl = label(db, "The linksets have been successfully moved.") apply(db, "OK", Continue) block db } close stPre; close stPost; delete skpLinks delete oldLinkSets delete oldLinkList